#pragma once

#include <list>
#include "atlctrlx.h"

#include "CURLHelper.h"
#include "FileDownInfoList.h"

using std::list;

//Predefine for compile
class CMainFrame;

class CMainDownListView : public CWindowImpl<CMainDownListView, CListViewCtrl>,
						  public CUpdateUI<CMainDownListView>,
						  public CIdleHandler
{
//Type definition
public:
	typedef enum _DOWN_LIST_TYPE {
		DOWNLIST_SCHEDULE = 0,
		DOWNLIST_SNIFFERING,
		DOWNLIST_READY,
		DOWNLIST_DOWNLOADING,
		DWONLIST_PAUSED,
		DONWLIST_FINISHED
	} DOWN_LIST_TYPE;

	typedef struct _DOWN_LIST_ITEM {
		wstring wstrFileName;
		FLOAT fFileMBSize;
		FLOAT fFinishedMBSize;
		UINT uiLeftSec;
		FLOAT fDownSpeedKBPS;

		string strURLRefer;
		string strDownLink;
		string strFileLink;
		string strSecIp;
		wstring wstrFileID;
		wstring wstrServerFileName;

		UINT uiItemIndex;
		DOWN_LIST_TYPE itemType;

		_DOWN_LIST_ITEM() : fFileMBSize(0.0), fFinishedMBSize(0.0), uiLeftSec(0), fDownSpeedKBPS(0.0), uiItemIndex(0) {}
		
	} DOWN_LIST_ITEM;

public:
	DECLARE_WND_CLASS(L"MainDownListView")

	BEGIN_UPDATE_UI_MAP(CMainDownListView)
		UPDATE_ELEMENT(ID_DOWNLIST_START, UPDUI_TOOLBAR | UPDUI_MENUPOPUP)
		UPDATE_ELEMENT(ID_DOWNLIST_PAUSE, UPDUI_TOOLBAR)
		UPDATE_ELEMENT(ID_DOWNLIST_STOP, UPDUI_TOOLBAR)
		UPDATE_ELEMENT(ID_DOWNLIST_DELETE, UPDUI_TOOLBAR)
		UPDATE_ELEMENT(ID_DOWNLIST_UP, UPDUI_TOOLBAR)
		UPDATE_ELEMENT(ID_DOWNLIST_DOWN, UPDUI_TOOLBAR)
		UPDATE_ELEMENT(ID_DOWNLIST_PROP, UPDUI_TOOLBAR)

	END_UPDATE_UI_MAP()

	BEGIN_MSG_MAP(CMainDownListView)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_TA_SNIFFER_LINK_STATUS, OnSnifferLink)
		MESSAGE_HANDLER(WM_DOWNLOADING_STATUS, OnDownloadingStatus)
		MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
		//WM_MENUSELECT is a noqueue msg, and won't be put into msg queue, the windows call the procedure directly
		//So we can't PreProccessing it, to pass it to the mainwindow, we have to hook here
		MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)

		COMMAND_ID_HANDLER(ID_DOWNLIST_START, OnDownItemStart)

		//The Header Custom Draw message will go to the listview window
		NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDrawHeader)

		CHAIN_MSG_MAP(CUpdateUI<CMainDownListView>)

	ALT_MSG_MAP(1)			//We check the msg from the parent window
		COMMAND_ID_HANDLER(ID_DOWNLIST_START, OnDownItemStart)
		NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDrawColumn)
	END_MSG_MAP()

public:
	CMainDownListView();
	~CMainDownListView();

	virtual BOOL OnIdle()
	{
		//We Handle the toolbar ourself
		UIUpdateToolBar();
		return FALSE;
	}

	void InitColumnHeader();
	void RefreshDownList(DOWN_LIST_TYPE downListType);
	void SnifferScheduledItems();
	void ClearPageLinkHeap();
	void ShowDownProperty();
	void OffSetCurrentListItemIndex(UINT uiOffset);

public:
	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnSnifferLink(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDownloadingStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	
	LRESULT OnDownItemStart(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);

	LRESULT OnCustomDrawHeader(int idCtrl, LPNMHDR lpnmhdr, BOOL& bHandled);
	LRESULT OnCustomDrawColumn(int idCtrl, LPNMHDR lpnmhdr, BOOL& bHandled);

public:
	list<DOWN_LIST_ITEM> m_lstDownListAll;
	vector<CCURLHelper::PAGE_LINK_ITEM*> m_vecPageLinkItem;			//This is for sniffer thread
	vector<CCURLHelper::TASK_DESCRIPTOR*> m_vecpDownTask;			//Hold downloading items
	CImageList m_imglstDummy;

	CMenu m_contMenu;
	CToolBarCtrl m_tbDownToolbar;
	CFileDownInfoList* m_pDownInfoListView;
	HWND m_hwndMainFrameWindow;

	CBitmap m_bmpSchedule;
	CBitmap m_bmpSniffering;
	CBitmap m_bmpReady;
	CBitmap m_bmpDonwloading;
	CBitmap m_bmpFinished;
	CBitmap m_bmpPaused;
	BLENDFUNCTION alphaBlendFunction;

	UINT m_nMaxParallelDownLoad;
};
